#ifndef __SELECT_SERVER_HPP_
#define __SELECT_SERVER_HPP_

#include <iostream>
#include "Socket.hpp"
#include <memory>
#include<unistd.h>
#include<poll.h>


static const int _Size = sizeof(fd_set) * 8;

class PollServer
{
private:
    void HandlerIO()
    {

        for (int i = 0; i < _Size; i++)
        {
            if(_fds[i].fd != -1)
            {
                if(_fds[i].revents & POLLIN)
                {
                    if(_fds[i].fd == _listensockfd->SockFd())
                    {
                        Accepter();
                    }

                    else 
                    {
                        Recver(_fds[i].fd);
                    }

                }
            }
        }
    }

    void Accepter()
    {
        std::cout << "fd 准备就绪" << std::endl;

        Inet_Addr _Client;
        int _sockfd = _listensockfd->Accept(&_Client);
        for (int i = 0; i < _Size; i++)
        {
            if (_fds[i].fd == -1)
            {
                _fds[i].fd = _sockfd;
                _fds[i].events = POLLIN;
                break;
            }
        }
    }

    void Recver(int fd)
    {
        char buffer[1024];
        ssize_t n = recv(fd,buffer,sizeof(buffer) -1,0);
        if(n > 0)
        {
            buffer[n] = 0;
            std::cout << buffer;
        }
        else if(n == 0)
        {
            std::cout << "对端关闭" << std::endl;
            for(int i = 0;i<_Size;i++)
            {
                if(_fds[i].fd == fd)
                {
                    _fds[i].fd = -1;
                    _fds[i].events = _fds[i].revents = 0;
                    break;
                }
            }
            close(fd);

        }
        else
        {
            for(int i = 0;i<_Size;i++)
            {
                if(_fds[i].fd == fd)
                {
                    _fds[i].fd = -1;
                    _fds[i].events = _fds[i].revents = 0;
                    break;
                }
            }
            close(fd);
        }
    }

public:
    PollServer(int _port) : _listensockfd(std::make_unique<TcpSocket>())
    {
        _listensockfd->BulidSocket(_port);
        for(int i = 0;i<_Size;i++)
        {
            _fds[i].fd = -1;
            _fds[i].events = _fds[i].revents = 0;
        }
        _fds[0].fd = _listensockfd->SockFd();
        _fds[0].events = POLLIN;
    }

    void Run()
    {
        while (1)
        {
           
            int n = poll(_fds,_Size,-1);
            switch (n)
            {
            case 0:
                std::cout << "time out" << std::endl;
                break;
            case -1:
                perror("poll");
                break;
            default:
                HandlerIO();
                break;
            }
        }
    }

    ~PollServer()
    {
    }

private:
    std::unique_ptr<Socket> _listensockfd;
    struct pollfd _fds[_Size];
};

#endif